package org.cybzacg.convert.converters.gather;

import org.cybzacg.convert.annotation.Converter;
import org.cybzacg.convert.enums.ConversionError;
import org.cybzacg.convert.enums.ConversionPriority;
import org.cybzacg.convert.enums.ConversionType;
import org.cybzacg.convert.exception.ConversionException;
import lombok.extern.slf4j.Slf4j;

import java.util.*;
import java.util.concurrent.*;

/**
 * Deque类型转换器
 * 支持各种Deque类型之间的转换
 *
 * @author cybzacg.blog
 * @version 4.0
 * @since 3.0
 */
@Slf4j
@Converter(name = "DequeConverter", priority = ConversionPriority.MEDIUM, description = "Deque类型转换器，支持各种Deque类型之间的转换", enabled = true, version = "4.0", author = "cybzacg.blog", supportedTypes = {
        Deque.class }, tags = { "deque", "collection", "conversion" })
public class DequeConverter extends AbstractCollectionConverter<Deque<Object>> {

    // Deque类型实现类映射
    private static final Map<Class<?>, Class<?>> DEQUE_IMPLEMENTATIONS = new HashMap<>();

    static {
        DEQUE_IMPLEMENTATIONS.put(Deque.class, ArrayDeque.class);
        DEQUE_IMPLEMENTATIONS.put(BlockingDeque.class, LinkedBlockingDeque.class);
    }

    public DequeConverter() {
        super(Deque.class, ConversionPriority.MEDIUM);
    }

    @Override
    protected ConversionType getConversionType() {
        return ConversionType.DEQUE;
    }

    @Override
    @SuppressWarnings("unchecked")
    protected <T> Deque<Object> createEmptyCollection(Class<T> targetType) {
        try {
            // 如果是具体的Deque实现类，直接实例化
            if (Deque.class.isAssignableFrom(targetType) &&
                    !targetType.isInterface() &&
                    !java.lang.reflect.Modifier.isAbstract(targetType.getModifiers())) {
                return (Deque<Object>) targetType.getDeclaredConstructor().newInstance();
            }

            // 根据接口类型选择实现类
            Class<?> implementationClass = DEQUE_IMPLEMENTATIONS.get(targetType);
            if (implementationClass != null) {
                return (Deque<Object>) implementationClass.getDeclaredConstructor().newInstance();
            }

            // 根据目标类型特征选择合适的实现
            if (targetType.getName().contains("LinkedList")) {
                return new LinkedList<>();
            } else if (targetType.getName().contains("LinkedBlockingDeque") ||
                    targetType.getName().contains("BlockingDeque")) {
                return new LinkedBlockingDeque<>();
            } else if (targetType.getName().contains("ConcurrentLinkedDeque")) {
                return new ConcurrentLinkedDeque<>();
            }

            // 默认使用ArrayDeque
            return new ArrayDeque<>();

        } catch (Exception e) {
            throw new ConversionException(ConversionError.CONVERSION_FAILED,
                    "无法创建Deque实例: " + targetType.getSimpleName(), e);
        }
    }

    @Override
    protected String getDefaultMapConversionMode() {
        return "entries"; // Deque默认转换Map的entries（支持双端操作）
    }

    @Override
    public String getName() {
        return "DequeConverter";
    }

    // ========== 静态工具方法 ==========

    /**
     * 检查是否为Deque类型
     */
    public static boolean isDequeType(Class<?> clazz) {
        return Deque.class.isAssignableFrom(clazz);
    }

    /**
     * 创建ArrayDeque的便捷方法
     */
    public static ArrayDeque<Object> toArrayDeque(Object source) {
        DequeConverter converter = new DequeConverter();
        try {
            return (ArrayDeque<Object>) converter.convertToCollection(source, ArrayDeque.class, null);
        } catch (Exception e) {
            throw new ConversionException(ConversionError.CONVERSION_FAILED,
                    "转换为ArrayDeque失败: " + source, e);
        }
    }

    /**
     * 创建LinkedList Deque的便捷方法
     */
    public static LinkedList<Object> toLinkedListDeque(Object source) {
        DequeConverter converter = new DequeConverter();
        try {
            return (LinkedList<Object>) converter.convertToCollection(source, LinkedList.class, null);
        } catch (Exception e) {
            throw new ConversionException(ConversionError.CONVERSION_FAILED,
                    "转换为LinkedList Deque失败: " + source, e);
        }
    }

    /**
     * 检查Deque是否为空或null
     */
    public static boolean isEmpty(Deque<?> deque) {
        return deque == null || deque.isEmpty();
    }

    /**
     * 获取Deque的安全大小
     */
    public static int safeSize(Deque<?> deque) {
        return deque != null ? deque.size() : 0;
    }
}
